package com.woniuxy.goods.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniuxy.core.util.StateNum;
import com.woniuxy.goods.dto.*;
import com.woniuxy.goods.entity.GoodsCat;
import com.woniuxy.goods.entity.GoodsCatPicture;
import com.woniuxy.goods.mapper.GoodsCatMapper;
import com.woniuxy.goods.param.*;
import com.woniuxy.goods.service.GoodsBrandCatService;
import com.woniuxy.goods.service.GoodsCatPictureService;
import com.woniuxy.goods.service.GoodsCatService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.goods.service.GroupTypeService;
import com.woniuxy.web.util.ConvertUtil;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 * 类别管理服务层实现类
 * @author ...
 * @since 2024年05月22日
 */
@Service
public class GoodsCatServiceImpl extends ServiceImpl<GoodsCatMapper, GoodsCat> implements GoodsCatService {
    /**
     * 品牌类别配置服务层接口
     */
    @Resource
    private GoodsBrandCatService goodsBrandCatService;
    /**
     * 类别属性组配置服务层接口
     */
    @Resource
    private GroupTypeService groupTypeService;
    /**
     * 类别鉴定图配置服务层接口
     */
    @Resource
    private GoodsCatPictureService catPictureService;


    /**
     * 新增典当物品类别
     * @param param 新增类别对象
     * @return 类别信息
     * @throws Exception
     */
    @Override
    @GlobalTransactional(rollbackFor = Throwable.class)
    public GoodsCat addGoodsCat(AddGoodsCatParam param) throws Exception {
        GoodsCat upCat = null;
        Integer state = StateNum.CAT_STATE_NORMAL;
        String router = null;
        if (param.getUpCatId()!=0){
            upCat = getById(param.getUpCatId());
            if (ObjectUtil.isEmpty(upCat)||upCat.getUpCatId()!=0) throw new Exception("一级类别不存在");
            state = upCat.getIsShow();
            router = upCat.getCatRoute();
        }
        QueryWrapper<GoodsCat> wrapper = new QueryWrapper<>();
        wrapper.eq("cat_name",param.getCatName());
        GoodsCat name = getOne(wrapper);
        if (ObjectUtil.isNotEmpty(name)) throw new Exception("该类别名称已存在");
        GoodsCat goodsCat = BeanUtil.toBean(param, GoodsCat.class);
        goodsCat.setIsShow(state);
        if (router!=null){
            router = router+">"+param.getCatName();
        }else {
            router = param.getCatName();
        }
        goodsCat.setCatRoute(router);
        List<GoodsCat> cats = list(new QueryWrapper<>());
        int size = cats.size()+1;
        String no = Integer.toString(size);
        if (no.length()<3){
            no = String.format("%03d",size);
        }
        goodsCat.setSortNo(no);
        save(goodsCat);
        System.out.println(goodsCat);
        if (goodsCat.getUpCatId()!=0){
            AddGroupTypeParam addGroupTypeParam = new AddGroupTypeParam();
            addGroupTypeParam.setGroupIds(param.getGroupIds());
            addGroupTypeParam.setCatId(goodsCat.getCatId());
            System.out.println(addGroupTypeParam);
            groupTypeService.addGroupType(addGroupTypeParam);
        }

        if (upCat!=null){
            String catLvl = upCat.getCatLvl();
            catLvl = catLvl+goodsCat.getCatId()+",";
            catLvl = catLvl.replace("null","");
            upCat.setCatLvl(catLvl);
            updateById(upCat);
        }
        for (AddCatPictureParam paramParam : param.getParams()) {
            paramParam.setCatId(goodsCat.getCatId());
            catPictureService.addCatPicture(paramParam);
        }
        return goodsCat;
    }

    /**
     * 修改典当物品类别
     * @param param 修改类别对象
     * @return 类别信息
     * @throws Exception
     */
    @Override
    @GlobalTransactional(rollbackFor = Throwable.class)
    public GoodsCat updateGoodsCat(UpdateGoodsCatParam param) throws Exception {
        //判断当前id是否存在
        GoodsCat goodsCat = getById(param.getCatId());
        if (ObjectUtil.isEmpty(goodsCat)) throw new Exception("当前类别不存在");
        //判断是否修改名称，修改后的名称是否重名
        if (!goodsCat.getCatName().equals(param.getCatName())){
            QueryWrapper<GoodsCat> wrapper = new QueryWrapper<>();
            wrapper.eq("cat_name",param.getCatName());
            GoodsCat name = getOne(wrapper);
            if (ObjectUtil.isNotEmpty(name)) throw new Exception("该类别名称已存在");
            goodsCat.setCatName(param.getCatName());
        }
        goodsCat.setCatDesc(param.getCatDesc());
        goodsCat.setUnit(param.getUnit());
        Integer state = null;
        //判断是否修改父级类别id
        if (goodsCat.getUpCatId()!=param.getUpCatId()){
            //判断原本的父级是否为0
            GoodsCat oldUp = null;
            if (goodsCat.getUpCatId()!=0){
                oldUp = getById(goodsCat.getUpCatId());
            }
            GoodsCat newCat = null;
            //判断是不是改为一级类别
            if (param.getUpCatId()!=0){
                //判断新父级是否存在
                newCat = getById(param.getUpCatId());
                if (ObjectUtil.isEmpty(newCat)||newCat.getUpCatId()!=0) throw new Exception("一级类别不存在");
            }
            //修改当前类别路径
            String route = null;
            if (newCat==null){
                route = param.getCatName();
            }else{
                route = newCat.getCatRoute()+">"+param.getCatName();
            }
            goodsCat.setCatRoute(route);
            //修改新父级类别子类别
            if (newCat!=null){
                String lvl = newCat.getCatLvl();
                lvl = lvl+goodsCat.getCatId()+",";
                lvl = lvl.replace("null","");
                newCat.setCatLvl(lvl);
            }
            //修改原父级子类别
            if (oldUp!=null){
                String lvl = oldUp.getCatLvl();
                lvl = lvl.replace(goodsCat.getCatId()+",","");
                oldUp.setCatLvl(lvl);
                updateById(oldUp);
            }
            //同步新父级状态
            if (newCat!=null){
                updateById(newCat);
                state = newCat.getIsShow();
            }
            goodsCat.setUpCatId(param.getUpCatId());
        }
        if (state!=null&&goodsCat.getIsShow()!=state){
            goodsCat.setIsShow(state);
            UpdateCatStateParam param1 = new UpdateCatStateParam();
            if (state==StateNum.CAT_STATE_NORMAL){
                param1.setCatId(goodsCat.getUpCatId());
            }else{
                param1.setCatId(goodsCat.getCatId());
            }
            param1.setIsShow(state);
            this.updateCatState(param1);
        }
        updateById(goodsCat);
        if (goodsCat.getUpCatId()!=0){
            AddGroupTypeParam addGroupTypeParam = new AddGroupTypeParam();
            addGroupTypeParam.setGroupIds(param.getGroupIds());
            addGroupTypeParam.setCatId(goodsCat.getCatId());
            System.out.println(addGroupTypeParam);
            groupTypeService.updateGroupTypeByCatId(addGroupTypeParam);
        }
        UpdateCatPictureByCatParam param1 = new UpdateCatPictureByCatParam();
        param1.setCatId(goodsCat.getCatId());
        param1.setParams(param.getParams());
        catPictureService.updateCatPictureByCat(param1);
        return goodsCat;
    }

    /**
     * 修改典当物品类别状态
     * @param param 修改类别状态对象
     * @return 类别信息
     * @throws Exception
     */
    @Override
    @GlobalTransactional(rollbackFor = Throwable.class)
    public GoodsCat updateCatState(UpdateCatStateParam param) throws Exception {
        GoodsCat goodsCat = getById(param.getCatId());
        if (ObjectUtil.isEmpty(goodsCat)) throw new Exception("当前类别不存在");
        //解禁
        if(param.getIsShow()==StateNum.CAT_STATE_NORMAL){
            UpdateWrapper<GoodsCat> wrapper = new UpdateWrapper<>();
            wrapper.set("is_show",StateNum.CAT_STATE_NORMAL);
            wrapper.and(v->v.eq("cat_id",param.getCatId()).or().eq("cat_id",goodsCat.getUpCatId()));
            update(null,wrapper);
            //禁用
        }else if(param.getIsShow()==StateNum.CAT_STATE_DISABLED){
            UpdateWrapper<GoodsCat> wrapper = new UpdateWrapper<>();
            wrapper.set("is_show",StateNum.CAT_STATE_DISABLED);
            wrapper.and(v->v.eq("cat_id",param.getCatId()).or().eq("up_cat_id",param.getCatId()));
            update(null,wrapper);
        }
        return goodsCat;
    }

    /**
     * 根据id查找典当物品类别
     * @param catId 类别id
     * @return 类别信息
     * @throws Exception
     */
    @Override
    public GoodsCat findCatById(Integer catId) {
        GoodsCat goodsCat = getById(catId);
        return goodsCat;
    }

    /**
     * 查找典当物品类别树
     * @return 类别信息树
     * @param brandId 品牌id
     * @throws Exception
     */
    @Override
    public List<GoodsCatTreeDto> findCatTree(Integer brandId) throws Exception {
        QueryWrapper<GoodsCat> wrapper = new QueryWrapper<>();
        if (brandId!=null){
            Set<Integer> catIds = goodsBrandCatService.findCatIdsByBrandId(brandId);
            wrapper.in("cat_id",catIds);
        }
        wrapper.eq("up_cat_id",0);
        wrapper.eq("is_show",StateNum.CAT_STATE_NORMAL);
        List<GoodsCat> goodsCats = list(wrapper);
        List<GoodsCatTreeDto> tree = new ArrayList<>();
        for (GoodsCat cat : goodsCats) {
            GoodsCatTreeDto dto = BeanUtil.toBean(cat, GoodsCatTreeDto.class);
            dto.setName(cat.getCatName());
            dto.setId(cat.getCatId());
            QueryWrapper<GoodsCat> wrapper1 = new QueryWrapper<>();
            wrapper1.eq("up_cat_id",cat.getCatId());
            wrapper1.eq("is_show",StateNum.CAT_STATE_NORMAL);
            List<GoodsCat> children = list(wrapper1);
            List<CatChildrenTreeDto> childrenDto = new ArrayList<>();
            for (GoodsCat child : children) {
                CatChildrenTreeDto catTreeDto = BeanUtil.toBean(child, CatChildrenTreeDto.class);
                catTreeDto.setName(child.getCatName());
                catTreeDto.setId(child.getCatId());
                List<GroupTypeDto> typeDtos = groupTypeService.findGroupTypeByCatId(catTreeDto.getId());
                Set<AttrGroupDto> attrGroupDtos = typeDtos.stream().map(o -> o.getGroupDto()).collect(Collectors.toSet());
                Set<AttrGroupTreeDto> groupTreeDtos = new HashSet<>();
                for (AttrGroupDto attrGroupDto : attrGroupDtos) {
                    AttrGroupTreeDto bean = BeanUtil.toBean(attrGroupDto, AttrGroupTreeDto.class);
                    bean.setName(attrGroupDto.getGroupName());
                    bean.setId(attrGroupDto.getGroupId());
                    groupTreeDtos.add(bean);
                }
                catTreeDto.setChildren(groupTreeDtos);
                childrenDto.add(catTreeDto);
            }
            dto.setChildren(new HashSet<>(childrenDto));
            tree.add(dto);
        }
        return tree;
    }

    /**
     * 通过ids查询典当物品类别
     * @param catIds 类别id集合
     * @return 类别信息集合
     * @throws Exception
     */
    @Override
    public List<GoodsCatDto> findCatByIds(Set<Integer> catIds) {
        QueryWrapper<GoodsCat> wrapper = new QueryWrapper<>();
        wrapper.in("cat_id",catIds);
        List<GoodsCat> goodsCats = list(wrapper);
        List<GoodsCatDto> goodsCatDtos = ConvertUtil.convertListTo(goodsCats, GoodsCatDto::new);
        for (GoodsCatDto goodsCatDto : goodsCatDtos) {
            QueryWrapper<GoodsCat> wrapper1 = new QueryWrapper<>();
            wrapper1.eq("up_cat_id",goodsCatDto.getCatId());
            List<GoodsCat> cats = list(wrapper1);
            List<GoodsCatDto> catDtos = ConvertUtil.convertListTo(cats, GoodsCatDto::new);
            goodsCatDto.setChildren(catDtos);
        }
        return goodsCatDtos;
    }

    /**
     * 通过ids查询典当物品一级类别
     * @param catIds 类别id集合
     * @return 类别信息集合
     * @throws Exception
     */
    @Override
    public List<GoodsCat> findOneCatByIds(Set<Integer> catIds) {
        QueryWrapper<GoodsCat> wrapper = new QueryWrapper<>();
        wrapper.in("cat_id",catIds);
        wrapper.eq("is_show",StateNum.CAT_STATE_NORMAL);
        wrapper.eq("up_cat_id",0);
        List<GoodsCat> goodsCats = list(wrapper);
        return goodsCats;
    }

    /**
     * 查找所有典当物品类别
     * @return 类别信息
     * @throws Exception
     */
    @Override
    public List<GoodsCatDto> findAllCat() {
        QueryWrapper<GoodsCat> wrapper = new QueryWrapper<>();
        wrapper.eq("up_cat_id",0);
        wrapper.in("is_show",StateNum.CAT_STATE_NORMAL);
        List<GoodsCat> goodsCats = list(wrapper);
        List<GoodsCatDto> goodsCatDtos = ConvertUtil.convertListTo(goodsCats, GoodsCatDto::new);
        for (GoodsCatDto goodsCatDto : goodsCatDtos) {
            QueryWrapper<GoodsCat> wrapper1 = new QueryWrapper<>();
            wrapper1.eq("up_cat_id",goodsCatDto.getCatId());
            List<GoodsCat> cats = list(wrapper1);
            List<GoodsCatDto> catDtos = ConvertUtil.convertListTo(cats, GoodsCatDto::new);
            goodsCatDto.setChildren(catDtos);
        }
        return goodsCatDtos;
    }

    @Override
    public List<GoodsCat> findAllSubCat() {
        QueryWrapper<GoodsCat> wrapper = new QueryWrapper<>();
        wrapper.ne("up_cat_id",0);
        wrapper.in("is_show",StateNum.CAT_STATE_NORMAL);
        return list(wrapper);
    }

    /**
     * 分页查询所有一级类别
     *
     * @param pageNum
     * @param pageSize
     * @param catName
     * @return
     */
    @Override
    public Page<GoodsCatDto> pageAllCat(Integer pageNum, Integer pageSize, String catName) throws Exception {
        Page<GoodsCat>page=new Page<>(pageNum,pageSize);
        QueryWrapper<GoodsCat> wrapper = new QueryWrapper<>();
//        wrapper.eq("up_cat_id",0);
        if(catName!=null&&catName!=""){
            wrapper.like("cat_name",catName);
        }
        this.page(page,wrapper);
        List<GoodsCat> goodsCats = page.getRecords();
        List<GoodsCatDto> goodsCatDtos = ConvertUtil.convertListTo(goodsCats, GoodsCatDto::new);
        for (GoodsCatDto goodsCatDto : goodsCatDtos) {
            QueryWrapper<GoodsCat> wrapper1 = new QueryWrapper<>();
            wrapper1.eq("up_cat_id",goodsCatDto.getCatId());
            List<GoodsCat> cats = list(wrapper1);
            List<GoodsCatDto> catDtos = ConvertUtil.convertListTo(cats, GoodsCatDto::new);
            goodsCatDto.setChildren(catDtos);
            List<GroupTypeDto> list = groupTypeService.findGroupTypeByCatId(goodsCatDto.getCatId());
            List<AttrGroupDto> collect = list.stream().map(o -> o.getGroupDto()).collect(Collectors.toList());
            goodsCatDto.setGroupTypeDtos(collect);
            List<GoodsCatPicture> picture = catPictureService.findPictureByCat(goodsCatDto.getCatId());
            List<GoodsCatPictureDto> dtoList = ConvertUtil.convertListTo(picture, GoodsCatPictureDto::new);
            goodsCatDto.setPicture(dtoList);
        }
        Page<GoodsCatDto>pages=new Page<>();
        pages.setPages(page.getPages());
        pages.setTotal(page.getTotal());
        pages.setCurrent(page.getCurrent());
        pages.setRecords(goodsCatDtos);
        pages.setSize(page.getSize());
        return pages;
    }

}
